package com.zxx.ssm.controller;

import com.github.pagehelper.PageInfo;
import com.zxx.ssm.dao.*;
import com.zxx.ssm.exception.AbstractServiceRuntimeException;
import com.zxx.ssm.model.biz.SigninoutBiz;
import com.zxx.ssm.model.biz.SigninoutSummaryBiz;
import com.zxx.ssm.model.convertor.SigninoutConvertor;
import com.zxx.ssm.model.enums.ResultCode;
import com.zxx.ssm.model.form.SigninoutForm;
import com.zxx.ssm.model.result.BizResponse;
import com.zxx.ssm.service.EmployeeService;
import com.zxx.ssm.service.FieldService;
import com.zxx.ssm.service.LeavesService;
import com.zxx.ssm.service.SigninoutService;
import com.zxx.ssm.util.DateUtils;
import com.zxx.ssm.util.PaginationUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * Created by OPTIPLEX on 2016/12/11.
 */

@RestController
@RequestMapping("signinout")
public class SigninoutController {
    @Autowired
    private SigninoutService signinoutService;

    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private LeavesService leavesService;

    @Autowired
    private FieldService fieldService;

    @RequestMapping(value = "getAll", method = RequestMethod.GET)
    @ResponseBody
    public BizResponse getSigninoutList(@ModelAttribute SigninoutForm signinoutForm, @RequestParam(defaultValue = "1") int pageNumber, @RequestParam(defaultValue = "1") int pageSize,
                                        @RequestParam(defaultValue = "id") String sort, @RequestParam(defaultValue = "desc") String order) {
        PaginationUtil.preset(pageNumber, pageSize, sort, order);
        List<SigninoutBiz> signinoutBizList = signinoutService.getAll(signinoutForm);
        PageInfo pageInfo = new PageInfo(signinoutBizList);
        BizResponse bizResponse = new BizResponse();
        bizResponse.put("signinout", pageInfo);
        return bizResponse;
    }
    @RequestMapping(value = "getAllSummary", method = RequestMethod.GET)
    @ResponseBody
    public BizResponse getSigninoutSummaryList(@ModelAttribute SigninoutForm signinoutForm, @RequestParam(defaultValue = "1") int pageNumber, @RequestParam(defaultValue = "10") int pageSize,
                                        @RequestParam(defaultValue = "id") String sort, @RequestParam(defaultValue = "asc") String order) {
        PaginationUtil.preset(pageNumber, pageSize, sort, order);
        List<SigninoutBiz> signinoutBizList = signinoutService.getAll(signinoutForm);



        FieldExample fieldExample = new FieldExample();
        FieldExample.Criteria field_criteria =  fieldExample.createCriteria();
        LeavesExample leavesExample = new LeavesExample();
        LeavesExample.Criteria leaves_criteria = leavesExample.createCriteria();
        SigninoutExample signinoutExample = new SigninoutExample();
        SigninoutExample.Criteria signinout_criteria = signinoutExample.createCriteria();



        if ((signinoutForm.getDateEnd() != null) && (signinoutForm.getDateEnd() != ""))
        {

            field_criteria.andStartTimeLessThanOrEqualTo(DateUtils.toDate(signinoutForm.getDateEnd()));
            leaves_criteria.andStartTimeLessThanOrEqualTo(DateUtils.toDate(signinoutForm.getDateEnd()));
            signinout_criteria.andDateLessThanOrEqualTo(DateUtils.toDate(signinoutForm.getDateEnd()));
        }
        if ((signinoutForm.getDateStart() != null) && (signinoutForm.getDateStart() != ""))
        {

            field_criteria.andEndTimeGreaterThanOrEqualTo(DateUtils.toDate(signinoutForm.getDateStart()));
            leaves_criteria.andEndTimeGreaterThanOrEqualTo(DateUtils.toDate(signinoutForm.getDateStart()));
            signinout_criteria.andDateGreaterThanOrEqualTo(DateUtils.toDate(signinoutForm.getDateStart()));
        }
        if (signinoutForm.getEmployeeCode()!=null && signinoutForm.getEmployeeCode()!="")
        {
            EmployeeExample employeeExample = new EmployeeExample();
            employeeExample.createCriteria().andCodeEqualTo(signinoutForm.getEmployeeCode());
            List<Employee> local_employees = employeeService.selectByExample(employeeExample);
            List<Integer> a = new ArrayList<Integer>();
            for (int i=0;i<local_employees.size();i++)
            {
                a.add(local_employees.get(i).getId());
            }


            signinout_criteria.andEmployeeCodeEqualTo(signinoutForm.getEmployeeCode());
            field_criteria.andEmployeeIdIn(a);
            leaves_criteria.andEmployeeIdIn(a);

        }
        field_criteria.andStateEqualTo(3);
        leaves_criteria.andStateEqualTo(3);

        List<Field> fields = fieldService.selectByExample(fieldExample);
        List<Leaves> leaves = leavesService.selectByExample(leavesExample);
        List<Signinout> signinouts = signinoutService.selectByExample(signinoutExample);

        List<SigninoutSummaryBiz> signinoutSummaryBizList= new ArrayList<SigninoutSummaryBiz>();

        HashMap map = new HashMap();
        for(int i=0;i<signinouts.size();i++)
        {
            Signinout s = signinouts.get(i);
            if (!map.containsKey(s.getEmployeeCode()))
            {
                SigninoutSummaryBiz ssb = new SigninoutSummaryBiz();
                ssb.setField_count(0);
                ssb.setSignin_count(0);
                ssb.setLeaves_count(0);
                EmployeeExample tempEmpExample = new EmployeeExample();
                tempEmpExample.createCriteria().andCodeEqualTo(s.getEmployeeCode());
                List<Employee> employeeList = employeeService.selectByExample(tempEmpExample);
                ssb.setEmployeeCode(s.getEmployeeCode());
                ssb.setEmployeeName(employeeList.get(0).getName());
                map.put(s.getEmployeeCode(),ssb);
            }

            SigninoutSummaryBiz ssb = (SigninoutSummaryBiz) map.get(s.getEmployeeCode());
            if (s.getStartTime() != null & s.getEndTime() != null) {
                ssb.setSignin_count(ssb.getSignin_count() + 1);
            }

        }
        for(int i=0;i<fields.size();i++)
        {
            Field f = fields.get(i);
            String code = employeeService.selectByPrimaryKey(f.getEmployeeId()).getCode();
            if (!map.containsKey(code))
            {
                SigninoutSummaryBiz ssb = new SigninoutSummaryBiz();
                ssb.setField_count(0);
                ssb.setSignin_count(0);
                ssb.setLeaves_count(0);
                EmployeeExample tempEmpExample = new EmployeeExample();
                tempEmpExample.createCriteria().andCodeEqualTo(code);
                List<Employee> employeeList = employeeService.selectByExample(tempEmpExample);
                ssb.setEmployeeCode(code);
                ssb.setEmployeeName(employeeList.get(0).getName());
                map.put(code,ssb);
            }
            SigninoutSummaryBiz ssb = (SigninoutSummaryBiz) map.get(code);

            int count = getcount(f.getStartTime(),f.getEndTime(),DateUtils.toDate(signinoutForm.getDateStart()),DateUtils.toDate(signinoutForm.getDateEnd()));


            ssb.setField_count(ssb.getField_count()+count);
        }
        for(int i=0;i<leaves.size();i++)
        {
            Leaves l = leaves.get(i);
            String code = employeeService.selectByPrimaryKey(l.getEmployeeId()).getCode();
            if (!map.containsKey(code))
            {
                SigninoutSummaryBiz ssb = new SigninoutSummaryBiz();
                ssb.setField_count(0);
                ssb.setSignin_count(0);
                ssb.setLeaves_count(0);
                ssb.setEmployeeCode(code);
                EmployeeExample tempEmpExample = new EmployeeExample();
                tempEmpExample.createCriteria().andCodeEqualTo(code);
                List<Employee> employeeList = employeeService.selectByExample(tempEmpExample);
                ssb.setEmployeeName(employeeList.get(0).getName());
                map.put(code,ssb);
            }
            SigninoutSummaryBiz ssb = (SigninoutSummaryBiz) map.get(code);

            int count = getcount(l.getStartTime(),l.getEndTime(),DateUtils.toDate(signinoutForm.getDateStart()),DateUtils.toDate(signinoutForm.getDateEnd()));
            ssb.setLeaves_count(ssb.getLeaves_count() + count);

        }
        for (Object key : map.keySet())
        {
            signinoutSummaryBizList.add((SigninoutSummaryBiz) map.get(key));
        }
        PageInfo pageInfo = new PageInfo(signinoutSummaryBizList);
        BizResponse bizResponse = new BizResponse();
        bizResponse.put("signinoutsummary", pageInfo);
        return bizResponse;
    }

    private int getcount(Date startTime, Date endTime, Date dateStart, Date dateEnd) {
        int count_date = 0;

        if (startTime==null | endTime==null)
        {
            return count_date;
        }
        Date max_date;
        if (dateStart == null)
        {
            max_date = startTime;
        }
        else if (startTime.before(dateStart)){
            max_date = dateStart;
        }
        else{
            max_date = startTime;
        }
        Date min_date;
        if (dateEnd == null)
        {
            min_date = endTime;
        }
        else if(endTime.before(dateEnd)){
            min_date = endTime;
        }
        else{
            min_date= dateEnd;
        }

        Calendar aCalendar = Calendar.getInstance();

        aCalendar.setTime(max_date);

        int day1 = aCalendar.get(Calendar.DAY_OF_YEAR);

        aCalendar.setTime(min_date);

        int day2 = aCalendar.get(Calendar.DAY_OF_YEAR);
        count_date = day2-day1;




        return count_date;
    }

    
    @RequestMapping(value = "", method = RequestMethod.POST)
    @ResponseBody
    public BizResponse addSigninout(@ModelAttribute SigninoutForm signinoutForm) {
        Signinout signinout = SigninoutConvertor.convertToSigninout(signinoutForm);

        SigninoutExample signinoutExample = new SigninoutExample();
        signinoutExample.createCriteria().andEmployeeCodeEqualTo(signinoutForm.getEmployeeCode()).andDateEqualTo(signinout.getDate());

        if( signinout.getStartTime()!=null & signinout.getEndTime()!=null )
        {
            if( signinout.getStartTime().after(signinout.getEndTime()))
            {
                return new BizResponse(ResultCode.SIGNINOUT_PROCESS_ERROR);
            }

        }
        EmployeeExample employeeExample = new EmployeeExample();

        employeeExample.createCriteria().andCodeEqualTo(signinoutForm.getEmployeeCode());

        List<Employee> local_employees = employeeService.selectByExample(employeeExample);

        if(employeeService.selectByExample(employeeExample).size() == 0)
        {

            return new BizResponse(ResultCode.SIGNINOUT_PROCESS_ERROR);
        }
        if(signinoutService.selectByExample(signinoutExample).size()  != 0 )
        {

            return new BizResponse(ResultCode.SIGNINOUT_PROCESS_ERROR);
        }
        if (signinoutService.insertSelective(signinout) > 0)
            return new BizResponse();
        else
            return new BizResponse(ResultCode.SIGNINOUT_PROCESS_ERROR);
    }

    @RequestMapping(value = "", method = RequestMethod.PUT)
    @ResponseBody
    public BizResponse updateSigninout(@ModelAttribute SigninoutForm signinoutForm) {
        Signinout signinout = SigninoutConvertor.convertToSigninout(signinoutForm);
        SigninoutExample signinoutExample = new SigninoutExample();

        if(signinout.getStartTime()!=null & signinout.getEndTime()!=null )
        {

            if (  signinout.getStartTime().after(signinout.getEndTime())) {
                return new BizResponse(ResultCode.SIGNINOUT_PROCESS_ERROR);
            }
        }

        signinoutExample.createCriteria().andIdEqualTo(signinout.getId());
        Signinout signinout1 = signinoutService.selectByPrimaryKey(signinout.getId());
        signinout1.setStartTime(signinout.getStartTime());
        signinout1.setEndTime(signinout.getEndTime());
        if (signinoutService.updateByExample(signinout1, signinoutExample) > 0)
            return new BizResponse();
        else
            return new BizResponse(ResultCode.SIGNINOUT_PROCESS_ERROR);
    }

    @RequestMapping(value = "/{strid}", method = RequestMethod.DELETE)
    @ResponseBody
    public BizResponse removeSigninout(@PathVariable("strid") String strid) {
        if (strid != null) {
            String[] idList = strid.split(",");
            for (int i = 0; i < idList.length; i++) {
                try {
                    Integer id = Integer.parseInt(idList[i]);
                    if (id != null)
                        signinoutService.delete(id);
                } catch (AbstractServiceRuntimeException e) {
                    e.printStackTrace();
                    return new BizResponse(ResultCode.SIGNINOUT_PROCESS_ERROR);
                }
            }
        }
        return new BizResponse();
    }

    @RequestMapping(value = "uploadFile", method = RequestMethod.POST)
    @ResponseBody
    public BizResponse uploadFile(){
        return null;
    }
}